#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "../Headers/msgqueue.h"
#include <sys/msg.h>
#include "../Headers/shared.h"
#include "../Headers/list.h"
#include <sys/shm.h>
#include <sys/sem.h>

#include "../Headers/sem.h"

typedef union semun {
	int val;
	struct semid_ds *buf;
	unsigned short *array;
}semun;

int
initsem(key_t semkey)
{
	int status = 0, semid;
	
	if((semid = semget(semkey, 2, SEMPERM|IPC_CREAT|IPC_EXCL)) == -1){
		if(errno == EEXIST)
			semid = semget(semkey, 1, 0);
	}else{
		semun arg;
		arg.val = 1;
		status = semctl(semid, 0, SETVAL, arg);
	}
	
	if ( semid == -1 || status == -1){
		perror("InitSem failed");
		return -1;
	}
	return semid;
}

int
p(int semid)
{
	struct sembuf p_buf;
	
	p_buf.sem_num = 0;
	p_buf.sem_op = -1;
	p_buf.sem_flg = SEM_UNDO;
	
	if(semop(semid, &p_buf, 1) == -1){
		perror("p(semid) failed");
		exit(1);
	}
	return 0;
}

int
v(int semid)
{
	struct sembuf v_buf;
		
	v_buf.sem_num = 0;
	v_buf.sem_op = 1;
	v_buf.sem_flg = SEM_UNDO;
	
	if(semop(semid, &v_buf, 1) == -1){
		perror("v(semid) failed");
		exit(1);
	}
	return 0;
}
